package juctest;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author 江岸
 * @version V1.0
 * @ClassName: TestReadWriterLock
 * @description: 我们在读数据的时候，可以多个线程同时读，不会出现问题，
 * 但是写数据的时候，如果多个线程同时写数据，那么到底是写入哪个线程的数据呢？
 * 所以，如果有两个线程，写写/读写需要互斥，读读不需要互斥。这个时候可以用读写锁。
 * @date 2021/3/2016:58
 * @since V1.0
 */
public class TestReadWriterLock {
    public static void main(String[] args){
        ReadWriterLockDemo rw = new ReadWriterLockDemo();
        ExecutorService pool = Executors.newFixedThreadPool(100);
        for (int i = 0;i<100;i++){//100个线程读
            Runnable runnable = () -> rw.get();
            //Thread thread = new Thread(runnable);
            //thread.start();
            pool.submit(runnable);
        }
        new Thread(new Runnable() {//一个线程写
            @Override
            public void run() {
                rw.set((int) (100*Math.random()));
            }
        },"write:").start();
    }
}

class ReadWriterLockDemo{
    private int number = 0;
    private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    //读(可以多个线程同时操作)
    public void get(){
        readWriteLock.readLock().lock();//上锁
        try {
            System.out.println(Thread.currentThread().getName()+":"+number);
        }finally {
            readWriteLock.readLock().unlock();//释放锁
        }
    }
    //写(一次只能有一个线程操作)
    public void set(int number){
        readWriteLock.writeLock().lock();
        try {
            this.number = number;
            Thread.sleep(10);
            System.out.println(Thread.currentThread().getName()+number);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            readWriteLock.writeLock().unlock();
        }
    }
}

